From: Konrad Rzeszutek Wilk Date: Thu, 19 Mar 2015 00:24:08 +0000 (-0400) Subject: libxc: Propagate errno from hypercall instead of anything else. X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~3558 X-Git-Url: https://dgit.raspbian.org/%22http:/www.example.com/cgi/%22https://%22%22/%22http:/www.example.com/cgi/%22https:/%22%22?a=commitdiff_plain;h=e12c6e8d186e42e659122461735ea38963c1d153;p=xen.git libxc: Propagate errno from hypercall instead of anything else. After we have done the hypercall - the errno has the failure code. However our usage of pthread and munmap can trigger them to manipulate the errno with their failure values. That would be bad as what we care about is just the hypercall error value. Another solution to this would be to save the 'errno' from pthread/munmap/madvise as an extra parameter to be analyzed later. However the call-sites above us do not care about it. Signed-off-by: Konrad Rzeszutek Wilk Acked-by: Ian Campbell --- diff --git a/tools/libxc/xc_freebsd_osdep.c b/tools/libxc/xc_freebsd_osdep.c index 151d3bfc57..e6613ef00a 100644 --- a/tools/libxc/xc_freebsd_osdep.c +++ b/tools/libxc/xc_freebsd_osdep.c @@ -125,10 +125,13 @@ static void freebsd_privcmd_free_hypercall_buffer(xc_interface *xch, int npages) { + int saved_errno = errno; /* Unlock pages */ munlock(ptr, npages * XC_PAGE_SIZE); munmap(ptr, npages * XC_PAGE_SIZE); + /* We MUST propagate the hypercall errno, not unmap call's. */ + errno = saved_errno; } static int freebsd_privcmd_hypercall(xc_interface *xch, xc_osdep_handle h, diff --git a/tools/libxc/xc_hcall_buf.c b/tools/libxc/xc_hcall_buf.c index e762a93a67..932b47c2ef 100644 --- a/tools/libxc/xc_hcall_buf.c +++ b/tools/libxc/xc_hcall_buf.c @@ -33,16 +33,22 @@ pthread_mutex_t hypercall_buffer_cache_mutex = PTHREAD_MUTEX_INITIALIZER; static void hypercall_buffer_cache_lock(xc_interface *xch) { + int saved_errno = errno; if ( xch->flags & XC_OPENFLAG_NON_REENTRANT ) return; pthread_mutex_lock(&hypercall_buffer_cache_mutex); + /* Ignore pthread errors. */ + errno = saved_errno; } static void hypercall_buffer_cache_unlock(xc_interface *xch) { + int saved_errno = errno; if ( xch->flags & XC_OPENFLAG_NON_REENTRANT ) return; pthread_mutex_unlock(&hypercall_buffer_cache_mutex); + /* Ignore pthread errors. */ + errno = saved_errno; } static void *hypercall_buffer_cache_alloc(xc_interface *xch, int nr_pages) diff --git a/tools/libxc/xc_linux_osdep.c b/tools/libxc/xc_linux_osdep.c index 92f7cace97..2687424305 100644 --- a/tools/libxc/xc_linux_osdep.c +++ b/tools/libxc/xc_linux_osdep.c @@ -122,10 +122,13 @@ out: static void linux_privcmd_free_hypercall_buffer(xc_interface *xch, xc_osdep_handle h, void *ptr, int npages) { + int saved_errno = errno; /* Recover the VMA flags. Maybe it's not necessary */ madvise(ptr, npages * XC_PAGE_SIZE, MADV_DOFORK); munmap(ptr, npages * XC_PAGE_SIZE); + /* We MUST propagate the hypercall errno, not unmap call's. */ + errno = saved_errno; } static int linux_privcmd_hypercall(xc_interface *xch, xc_osdep_handle h, privcmd_hypercall_t *hypercall)